package com.pfsbuilder;

import java.io.File;
import java.util.Arrays;
import java.util.Vector;

import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

/**
 * <p>
 * Title: PFS
 * </p>
 * 
 * <p>
 * Description:
 * </p>
 * 
 * <p>
 * Copyright: Copyright (c) 2005
 * </p>
 * 
 * <p>
 * Company: Petersoft
 * </p>
 * 
 * @author Peter
 * @version 2005
 */

public class PFSTreeModel implements TreeModel {
	private Vector treeModelListeners = new Vector();
	private File rootNode;

	public PFSTreeModel(String filepath) {
		super();
		rootNode = new File(filepath);
	}

	// ////////////// Fire events //////////////////////////////////////////////

	/**
	 * The only event raised by this model is TreeStructureChanged with the root
	 * as path, i.e. the whole tree has changed.
	 */
	public void fireTreeStructureChanged(File oldRoot) {
		int len = treeModelListeners.size();
		TreeModelEvent e = new TreeModelEvent(this, new Object[] { oldRoot });
		for (int i = 0; i < len; i++) {
			((TreeModelListener) treeModelListeners.elementAt(i)).treeStructureChanged(e);
		}
	}

	// ////////////// TreeModel interface implementation ///////////////////////

	/**
	 * Adds a listener for the TreeModelEvent posted after the tree changes.
	 */
	public void addTreeModelListener(TreeModelListener l) {
		treeModelListeners.addElement(l);
	}

	/**
	 * Returns the child of parent at index index in the parent's child array.
	 */
	public Object getChild(Object parent, int index) {
		// System.out.println("getChild");
		return getChildren(parent)[index];
	}

	private Object[] getChildren(Object node) {
		// System.out.println("getChildren");
		File fileNode = (File) node;
		File[] selectedFiles = fileNode.listFiles();
		Arrays.sort(selectedFiles, new FileComparator());
		return selectedFiles;
	}

	/**
	 * Returns the number of children of parent.
	 */
	public int getChildCount(Object parent) {
		try {
			File p = (File) parent;
			// System.out.println(p.toString()+"="+p.listFiles().length);
			return p.listFiles().length;
		} catch (Exception ex) {
			return 0;
		}
	}

	/**
	 * Returns the index of child in parent.
	 */
	public int getIndexOfChild(Object parent, Object child) {
		// System.out.println("getIndexOfChild");
		File p = (File) parent;
		File[] selectedFiles = p.listFiles();
		Arrays.sort(selectedFiles, new FileComparator());
		for (int x = 0; x < p.listFiles().length; x++) {
			if (selectedFiles[x].equals(child)) {
				return x;
			}
		}
		return -1;
	}

	/**
	 * Returns the root of the tree.
	 */
	public File getRoot() {
		return rootNode;
	}

	/**
	 * Returns true if node is a leaf.
	 */
	public boolean isLeaf(Object node) {
		try {
			File p = (File) node;
			if (p.isDirectory()) {
				return false;
			} else {
				return true;
			}
		} catch (Exception ex) {
			return true;
		}
	}

	/**
	 * Removes a listener previously added with addTreeModelListener().
	 */
	public void removeTreeModelListener(TreeModelListener l) {
		treeModelListeners.removeElement(l);
	}

	/**
	 * Messaged when the user has altered the value for the item identified by
	 * path to newValue. Not used by this model.
	 */
	public void valueForPathChanged(TreePath path, Object newValue) {
		System.out.println("*** valueForPathChanged : " + path + " --> " + newValue);
	}

	public TreePath getTreePath(File file) {
		Vector tempVector = new Vector();
		File tempFile = file;
		do {
			tempVector.add(tempFile);
			tempFile = tempFile.getParentFile();
		} while (!tempFile.equals(this.getRoot()));
		tempVector.add(tempFile);
		return new TreePath(CommonLib.reverseArray(tempVector.toArray()));
	}
}
